"""
业务流程定义

拆解业务流程
每一个环节都作为一个独立的仿真模块，每个模块都有一个自己的资源控制

卡车生成模块
这块模拟的是 根据货物参数，生成匹配的多辆卡车，这个卡车不是一次性生成的，每生成一辆都需要检测卡车停靠站有没有空位
没有空位的话等待，有空位的话生成一辆卡车 开入停靠站

卡车进入【卡车停靠站】模块
停靠站作为一个资源，控制着有多少个停车位，也就是这个停车场还有没有空位
当停靠站满了时，无法接收新卡车进入除非有卡车离开，有空位时给一个资源编号（如停车位编号），方便三维的还原，同时也可以更好计算时间和每个车位的利用率等

【入口】传送带模块
这个模块自行检测，当有空闲时就去【卡车停靠站】检测有没有还未卸货的车
有的话，就调用空闲卡车进入该入口 ，到达入口后开始卸货，卸货完成后，卡车离开【入口】，释放占有，继续重复检测【卡车停靠站】有没有还未卸货的车这个步骤
当卸货时，每次卸货都需要检测【类型筛选平台】是否超容积，超容积的话，就停止卸货，等待【类型筛选平台】有空位

【类型筛选平台】模块
这个模块比较简单，只需要设定一定量的容积，比如可以放多少个在这个平台上，当这个平台满了，就停止【入口】的货物输入，等待这个平台有空位再恢复输入
自身有一逻辑（如按比例实现货物类型的分配以及识别率），当货物进入这个平台时，会根据这个逻辑进行货物类型的分配如进入各个类型池还是继续留在平台

【类型池分类平台】模块
这里有三个类型：普通-危险-冷藏，所以生成三个分类平台，这里的分类平台主要是将货物分配到哪个出口，给定信息之后会放置在对应的临时停放区，等待无人车运输
这个临时停放区的个数可以根据参数配置，以及跟出口的比值，比如出口有10个，临时停放区有5个，那么每个出口就有2个临时停放区



【无人车运输】模块
寻找所有的临时停放池，哪里已经满了以及以及哪一组的空闲比最小优先去这一组运输

【出口】模块
对应各个出口，出口有开放和是否占用的三种状态
【临时停放池】模块
附属在【类型池分类平台】模块中，也就是会被按需分配到某个类型池分类平台中，当货物被分配到某个类型池后，会进入对应的临时停放池，等待无人车运输
【出口卡车停靠站】模块
仿入口的卡车停靠站模块，由卡车生成模块生成卡车，分配卡车









卡车生成模块
货物数量换算卡车数量
货物：根据分配，把对应货物分配到对应的卡车
根据配置生成出口卡车

卡车
状态：未到达-到达-未卸货-卸货中-卸货完成-离开
归属：入口卡车停靠站-出口卡车停靠站

卡车停靠站
车位编号，分配对应的车位编号给车辆
车位状态：被占用-空闲
属性：出口-入口


入口
状态：被占用-空闲
货物：从卡车获取对用的货物编号 放入类型筛选平台中，模拟货物放入平台


类型筛选平台
随机选中一个货物，将其分配到类型池中

类型池分类平台
随机选中一个货物，将其分配到某个类型。并放在对应的停放区，或者进入人工筛选池进行筛选，最终放入对应临时停放区


总的临时停放池管理平台
临时停放池列表

临时停放池
容积
所属类型池分类平台
对应出口

无人车运输
车辆数量
获取任务的对应出口

出口
状态：未开放-占用-空闲
未开放的状态属于当前出口无卡车，所以送过去没有卡车接收

"""

from dataclasses import dataclass,field
from typing import Optional 
from config.warehouse_config import ENTER_NUM,EXIT_NUM, GOODS_NUM,TRUCK_CAPACITY,AGV_NUM,ENTER_PARKING_CAPACITY,EXIT_PARKING_CAPACITY,TYPE_POOL_CAPACITY,TYPE_POOL_WARNING,NORMAL_TYPE_POOL_CAPACITY,NORMAL_TYPE_POOL_WARNING,DANGEROUS_TYPE_POOL_CAPACITY,DANGEROUS_TYPE_POOL_WARNING,REFRIGERATED_TYPE_POOL_CAPACITY,REFRIGERATED_TYPE_POOL_WARNING,GOODS_RECOGNITION_RATIO,AGV_PICKUP_POINT_CAPACITY,EXIT_CAPACITY,EXIT_CAPACITY_WARNING,MACHINE_RECOGNITION_RATIO
from models.entities import Enter,Exit,Goods,Truck,AGV,NormalTypePool,DangerousTypePool,RefrigeratedTypePool,AGVPickupPoint,TypePool,AGV
from storage.sqlite_storage import SQLiteStorage
import random
import math
import simpy
import uuid

from storage import *





@dataclass
class SimObjManager:
     
    """ 
    出入口模块
    """
    enter_dict:dict=field(default_factory=dict)
    exit_dict:dict=field(default_factory=dict)
    """ 
    货物模块
    """
    goods_dict:dict=field(default_factory=dict)
    """ 
    卡车模块
    """
    truck_dict:dict=field(default_factory=dict)
    """ 
    无人agv车辆模块
    """
    agv_dict:dict=field(default_factory=dict)
    """ 
    类型池模块
    """
    type_pool_dict:dict=field(default_factory=dict)
    """ 
    临时停放池模块
    """
    agv_pickup_point_dict:dict=field(default_factory=dict)


    env:simpy.Environment=field(default=None) # type: ignore
    

    
    def __post_init__(self)->None:
        """初始化"""
        if self.env is None:
            print("请传入simpy环境")

        """ 出入口模块初始化 ，直接生成对应的出入口，放入dict中 """
        for i in range(ENTER_NUM):
            enter=Enter()
            self.enter_dict[enter.id]=enter
            
        for i in range(EXIT_NUM):
            exit=Exit()
            exit.name=f"{i}"
            exit.capacity=EXIT_CAPACITY
            exit.warning_capacity=EXIT_CAPACITY_WARNING
            self.exit_dict[exit.id]=exit
        
        """ 货物模块初始化 ，直接生成对应的货物，放入dict中 """
        for i in range(GOODS_NUM):
            goods=Goods()
            goods.id=f"goods_{i:06d}"  # 使用递增ID，6位数字，确保唯一性
            # danger normal refrigerated 这三个按照比例生成
            goods.type=random.choices(['danger','normal','refrigerated'],weights=[0.2,0.6,0.2])[0]
            goods.exit_No=random.choice(list(self.exit_dict.keys())) #随机一个出口index #f"{random.randint(0,GOODS_NUM-1)%EXIT_NUM}" # 随机归属对应的出口
            self.goods_dict[goods.id]=goods
            # 存入数据库中
            insert_goods_b(goods,self.env)
            # 存入初始状态
            insert_status_b(goods.id,"goods","spawn",self.env)
        
        """ 卡车模块初始化 ，直接生成对应的卡车，放入dict中 """
        # 计算需要的卡车数量：货物总数/卡车容量，向上取整
        truck_num_in=math.ceil(GOODS_NUM/TRUCK_CAPACITY)
        # 根据卡车容量将货物分成对应的list
        goods_list=list(self.goods_dict.values())
        goods_list_split=[goods_list[i:i+TRUCK_CAPACITY] for i in range(0,len(goods_list),TRUCK_CAPACITY)]
        # 将分配的货物装入对应的卡车
        total_goods_in_trucks = 0
        for i in range(truck_num_in):
            truck=Truck()
            truck.type="in"
            truck.name=f"in_truck_{i}"
            # 确保不会超出goods_list_split的范围
            if i < len(goods_list_split):
                truck.goods_list=goods_list_split[i]
            else:
                truck.goods_list=[]
            self.truck_dict[truck.id]=truck
            total_goods_in_trucks += len(truck.goods_list)
            # print(f"卡车{truck.id}生成 ，货物数量：{len(truck.goods_list)}")
            insert_vehicle_b(truck,self.env)
            # 存入初始状态
            insert_status_b(truck.id,"in_truck","spawn",self.env)
            
        
        print(f"=== 卡车生成统计 ===")
        print(f"总货物数量: {GOODS_NUM}")
        print(f"实际生成货物数量: {len(goods_list)}")
        print(f"计算卡车数量: {truck_num_in}")
        print(f"卡车中货物总数: {total_goods_in_trucks}")
        print(f"货物分配率: {total_goods_in_trucks/GOODS_NUM*100:.2f}%")
        

        #我需要根据 货物的出口类型，exit_No 分类，按照每一类的数量生成对应的卡车数量
        goods_list_by_exit_No={}
        for goods in self.goods_dict.values():
            if goods.exit_No not in goods_list_by_exit_No:
                goods_list_by_exit_No[goods.exit_No]=[]
            goods_list_by_exit_No[goods.exit_No].append(goods)

        # 根据 goods_list_by_exit_No 生成对应的卡车数量
        for exit_No,goods_list in goods_list_by_exit_No.items():
            truck_num_out=math.ceil(len(goods_list)/TRUCK_CAPACITY)
            goods_list_split=[goods_list[i:i+truck_num_out] for i in range(0,len(goods_list),truck_num_out)]
            for i in range(truck_num_out):
                truck=Truck()
                truck.type="out"
                truck.name=f"out_truck_{exit_No}_{i}"
                truck.goods_list=[]
                self.truck_dict[truck.id]=truck
                insert_vehicle_b(truck,self.env)
                insert_status_b(truck.id,"out_truck","spawn",self.env)

        # 生成无人agv车辆
        for i in range(AGV_NUM):
            agv=AGV()
            agv.name=f"agv_{i}"
            self.agv_dict[agv.id]=agv
            insert_vehicle_b(agv,self.env)
            insert_status_b(agv.id,"agv","spawn",self.env)
        
        # 生成一个类型池 用于筛选货物类型
        type_pool=TypePool()
        type_pool.name=f"type_pool"
        self.type_pool_dict[type_pool.name]=type_pool

        # 生成三类分类池
        normal_type_pool=NormalTypePool()
        dangerous_type_pool=DangerousTypePool()
        refrigerated_type_pool=RefrigeratedTypePool()
        # 生成对应的类型分类池
        normal_type_pool.name=f"normal_type_pool"
        dangerous_type_pool.name=f"dangerous_type_pool"
        refrigerated_type_pool.name=f"refrigerated_type_pool"
        self.type_pool_dict[normal_type_pool.name]=normal_type_pool
        self.type_pool_dict[dangerous_type_pool.name]=dangerous_type_pool
        self.type_pool_dict[refrigerated_type_pool.name]=refrigerated_type_pool

        # 根据出口，在对应的出口生成对应的临时停放池
        for exit in self.exit_dict.values():
            """ 
            normal 每个出口2个
            dangerous 每个出口1个
            refrigerated 每个出口1个
            """
            agv_pickup_point=AGVPickupPoint()
            agv_pickup_point.name=f"agv_pickup_point_{exit.id}"
            agv_pickup_point.type_pool_id=normal_type_pool.name
            agv_pickup_point.exit_id=exit.id
            self.agv_pickup_point_dict[f"normal_1_{exit.id}"]=agv_pickup_point

            agv_pickup_point=AGVPickupPoint()
            agv_pickup_point.name=f"agv_pickup_point_{exit.id}"
            agv_pickup_point.type_pool_id=normal_type_pool.name
            agv_pickup_point.exit_id=exit.id
            self.agv_pickup_point_dict[f"normal_2_{exit.id}"]=agv_pickup_point

            agv_pickup_point=AGVPickupPoint()
            agv_pickup_point.name=f"agv_pickup_point_{exit.id}"
            agv_pickup_point.type_pool_id=dangerous_type_pool.name
            agv_pickup_point.exit_id=exit.id
            self.agv_pickup_point_dict[f"dangerous_{exit.id}"]=agv_pickup_point

            agv_pickup_point=AGVPickupPoint()
            agv_pickup_point.name=f"agv_pickup_point_{exit.id}"
            agv_pickup_point.type_pool_id=refrigerated_type_pool.name
            agv_pickup_point.exit_id=exit.id
            self.agv_pickup_point_dict[f"refrigerated_{exit.id}"]=agv_pickup_point
        
        # 强制刷新所有数据数据库中
        force_flush_batch()
        

             
        


@dataclass
class SimProcess:
    """仿真流程"""
    sim_obj_manager:SimObjManager=field(default=None) # type:ignore
    db_storage:SQLiteStorage=field(default_factory=SQLiteStorage)
    env:simpy.Environment=None # type: ignore
    # 停靠站资源
    enter_parking_resource:simpy.Resource=None # type: ignore
    exit_parking_resource:simpy.Resource=None # type: ignore
    # 存储每辆卡车的资源请求对象
    truck_parking_requests:dict=field(default_factory=dict)
    # 分类平台的总资源：可以接收的总的货物数量 超过了就需要暂停
    type_pool_capacity_resource:simpy.Resource=None # type: ignore
    # 分类平台的资源请求对象存储，用于后续释放时可用
    type_pool_requests:dict=field(default_factory=dict)

    # 各个类型池的子分类平台资源
    type_pool_sub_capacity_resources:dict=field(default_factory=dict)
    # 类型池的出口分类平台资源请求对象存储，用于后续释放时可用
    type_pool_sub_requests:dict=field(default_factory=dict)

    # 临时停放池的资源
    agv_pickup_point_resources:dict=field(default_factory=dict)
    # 临时停放池的资源请求对象存储，用于后续释放时可用
    agv_pickup_point_requests:dict=field(default_factory=dict)

    # 记录一个已卸货的货物统计
    exit_goods_count:int=0
    # 记录已将装货的货物统计
    truck_load_count:int=0

    # 出口的缓冲区资源
    exit_buffer_resources:dict=field(default_factory=dict)
    # 出口的缓冲区资源请求对象存储，用于后续释放时可用
    exit_buffer_requests:dict=field(default_factory=dict)
    

    def __post_init__(self):
        """初始化"""

        self.sim_obj_manager=SimObjManager(env=self.env)

        # 正确赋值给实例变量
        self.enter_parking_resource = simpy.Resource(self.env, capacity=ENTER_PARKING_CAPACITY)
        self.exit_parking_resource = simpy.Resource(self.env, capacity=EXIT_PARKING_CAPACITY)
        self.type_pool_capacity_resource = simpy.Resource(self.env, capacity=TYPE_POOL_CAPACITY)
        # 类型池的子分类平台资源
        self.type_pool_sub_capacity_resources["normal_type_pool"]=simpy.Resource(self.env, capacity=NORMAL_TYPE_POOL_CAPACITY)
        self.type_pool_sub_capacity_resources["dangerous_type_pool"]=simpy.Resource(self.env, capacity=DANGEROUS_TYPE_POOL_CAPACITY)
        self.type_pool_sub_capacity_resources["refrigerated_type_pool"]=simpy.Resource(self.env, capacity=REFRIGERATED_TYPE_POOL_CAPACITY)
        # 临时停放池的资源,针对每个出口的临时停放池，生成对应的资源
        for exit in self.sim_obj_manager.exit_dict.values():
            self.agv_pickup_point_resources[f"normal_1_{exit.id}"]=simpy.Resource(self.env, capacity=AGV_PICKUP_POINT_CAPACITY)
            self.agv_pickup_point_resources[f"normal_2_{exit.id}"]=simpy.Resource(self.env, capacity=AGV_PICKUP_POINT_CAPACITY)
            self.agv_pickup_point_resources[f"dangerous_{exit.id}"]=simpy.Resource(self.env, capacity=AGV_PICKUP_POINT_CAPACITY)
            self.agv_pickup_point_resources[f"refrigerated_{exit.id}"]=simpy.Resource(self.env, capacity=AGV_PICKUP_POINT_CAPACITY)
            #给每一个出口设定一个缓冲区
            self.exit_buffer_resources[exit.id]=simpy.Resource(self.env, capacity=exit.capacity)
        
        




    """ 
    停车站检测卡车是否能进入，类似对场外排队进站的车辆叫号
    """
    def _run_truck_in(self):
        """运行卡车进入停靠站流程
        需要获取停靠站，同时检查是否还有货车未开入停车站，并获取当前的停靠站所有的车位有没有都被占用 都满足了，则放一辆车进来
        """
        while True:
            yield self.env.timeout(10)
            # 检查是否还有货车未开入停车站
            if len(self.sim_obj_manager.truck_dict) > 0:
                # 筛选truck type为 in ,并且status为spawn的卡车
                truck_list=[]
                for truck in self.sim_obj_manager.truck_dict.values():
                    if truck.type == "in" and truck.status == "spawn":
                        truck_list.append(truck)
                # 如果truck_list不为空，则获取一辆车
                if len(truck_list) > 0:
                    # 获取一辆车
                    truck=truck_list[0]
                    # print(f"放行卡车进入停车位{truck.id}")
                    # 申请停车位资源
                    parking_request = self.enter_parking_resource.request()
                    yield parking_request  # 等待获得资源
                    # 将请求对象保存到字典中，后续释放时使用
                    self.truck_parking_requests[truck.id] = parking_request
                    # 增加存储车辆状态的逻辑
                    insert_status_b(truck.id,"in_truck","to_waiting",self.env)
                    # 修改车辆状态，设置成waiting，再模拟车辆从外部开到车位上
                    truck.status="to_waiting"
                    yield self.env.process(self._autorun_truck_in(truck.id))
                    # 增加存储车辆状态的逻辑
                    insert_status_b(truck.id,"in_truck","to_waiting",self.env)
                    #yield self.env.timeout(1)

    """ 
    卡车进入停车场的过程，模拟从入口开到停车位
    """
    def _autorun_truck_in(self,truck_id:str):
        """自动运行卡车进入停靠站流程"""
        truck=self.sim_obj_manager.truck_dict[truck_id]
        # print(f"车辆{truck_id}从外部开到车位")
        yield self.env.timeout(20) # 模拟从外部开到车位
        truck.status="waiting"
        insert_status_b(truck.id,"in_truck","waiting",self.env)
        # print(f"车辆{truck_id}从外部开到车位完成")

    """ 
    每个入口都绑定一个检测函数，先去检测是否有正在等待卸货的卡车，如果有，就申请卸货，绑定卡车后卡车开入这个入口，开始卸货
    直到卸货完成后，进入下一轮的检测
    """
    def _run_truck_Enter(self,enter_id:str):
        """ 卡车从车位走到入口，多个入口，每个入口都需要进入这个检测流程"""
        # print(f"当前入口{enter_id} 开始走卸货流程")
        #检查入口停车场上有没有车待卸货：这有两种方式可以做，第一种，直接检测 enter_parking_resource count 是否大于0，第二种，检测有没有truck status 是 waiting
        # 这里使用第二种方式
        while True:
            yield self.env.timeout(2)
            # 检查有没有truck status 是 waiting 并且 type 是 in 的卡车
            truck_list=[]
            for truck in self.sim_obj_manager.truck_dict.values():
                if truck.status == "waiting" and truck.type == "in":
                    truck_list.append(truck)

            if len(truck_list) > 0:
                # print(f"当前入口{enter_id} 等待卸货的卡车数量：{len(truck_list)}")
                # 获取一辆车
                truck=truck_list[0]
                insert_status_b(truck.id,"in_truck","to_unloading",self.env)
                # 修改车辆状态，设置成unloading，再模拟车辆从车位到入口
                truck.status="unloading"
                # 释放停车位资源 - 使用保存的请求对象
                if truck.id in self.truck_parking_requests:
                    parking_request = self.truck_parking_requests[truck.id]
                    self.enter_parking_resource.release(parking_request)
                    # 从字典中移除已释放的请求
                    del self.truck_parking_requests[truck.id]
                # 等待卸货进程完全完成，确保锁的正确释放
                # print(f"入口{enter_id} 锁定成功，开始处理车辆{truck.id}")
                yield self.env.process(self._autorun_truck_Enter(truck.id, enter_id))
                insert_status_b(truck.id,"in_truck","unload_finish",self.env)
                # print(f"入口{enter_id} 车辆{truck.id}处理完成，锁已释放，准备处理下一辆车")
    """ 
    卸货口的具体卸货流程
    每隔卸货口卸每一件货时，都会先申请一个卸货指标，得到指标后才可以卸货，否则需要等待指标发放。否则就会爆仓
    获取指标后，再减少卡车里的货物，增加分类平台上的货物
    完成后进入下一轮的检测
    """     
    def _autorun_truck_Enter(self,truck_id:str, enter_id:str):
        """自动运行卡车进入入口流程"""
        truck=self.sim_obj_manager.truck_dict[truck_id]
        #print(f"车辆{truck_id}从车位开到入口{enter_id} ")
        yield self.env.timeout(50) # 模拟从车位开到入口
        # 记录车辆到达卸货口
        insert_status_b(truck.id,"in_truck","unloading",self.env)
        #print(f"车辆{truck_id}从车位开到入口完成，开始卸货")
        # 这里添加卸货逻辑
        while True:
            yield self.env.timeout(5)
            # 检查货物是否卸完
            if len(truck.goods_list) == 0:
                # 修改车辆状态，设置成finish
                truck.status="finish"
                break
            # 获取第一个货物，将其放入类型筛选平台
            goods=truck.goods_list[0]
            # 删除货物
            truck.goods_list.pop(0)
            # 修改货物状态，设置成 type check
            goods.status_list.append("type_check")
            # 用于请求资源，需要等待分类池有空位才可以进入
            req= self.type_pool_capacity_resource.request()  
            yield req 
            # 将请求对象保存到字典中，后续释放时使用
            self.type_pool_requests[goods.id] = req
            # 将货物放入类型筛选平台  
            self.sim_obj_manager.type_pool_dict["type_pool"].goods_list.append(goods)
            insert_status_b(goods.id,"goods","type_pool",self.env)
            # 立即获取当前数量，避免并发问题
            current_count = len(self.sim_obj_manager.type_pool_dict["type_pool"].goods_list)
            #print(f"[入口{enter_id}] 货物{goods.id}到达类型分类平台，当前类型分类平台货物数量：{current_count}")
            yield self.env.timeout(3) # 模拟货物在类型分类平台用时2秒

    """ 
    分类平台分类逻辑
    这里先将分类平台上的货物，暂时按照6：2：2分配到对应的出口分类池中。普通 危险 冷藏
    在分类过程中，再增加每次的识别率，增加一点随机性
    """
    def _type_pool_process(self):
        """ 类型池分类平台流程 """
        while True:
            # 快速分拣，每0.3秒分拣一个货物
            yield self.env.timeout(10)
            # 检查有没有货物在类型池中
            if len(self.sim_obj_manager.type_pool_dict["type_pool"].goods_list) == 0:
                continue
            for i in range(2):
                if len(self.sim_obj_manager.type_pool_dict["type_pool"].goods_list) == 0:
                    break
                # 随机一个数 0-1 的数，看是否能满足 大于 GOODS_RECOGNITION_RATIO
                random_num=random.random()
                if random_num < GOODS_RECOGNITION_RATIO:
                    # 获取第一个货物
                    goods=self.sim_obj_manager.type_pool_dict["type_pool"].goods_list[0]
                    # 删除货物
                    self.sim_obj_manager.type_pool_dict["type_pool"].goods_list.pop(0)
                    # 修改货物状态，设置成 type check
                    goods.status_list.append(f"type_check_finish_{goods.type}")
                    # 释放资源
                    if goods.id in self.type_pool_requests:
                        req = self.type_pool_requests[goods.id]
                        self.type_pool_capacity_resource.release(req)
                        del self.type_pool_requests[goods.id]
                    # 将货物放入对应的分类池
                    if goods.type == "normal":
                        #self.sim_obj_manager.type_pool_dict["normal_type_pool"].goods_list.append(goods)
                        insert_status_b(goods.id,"goods","to_normal_type_pool",self.env)
                        self.env.process(self._type_pool_exit_process_receive("normal_type_pool",goods))
                    elif goods.type == "danger":
                        #self.sim_obj_manager.type_pool_dict["dangerous_type_pool"].goods_list.append(goods)
                        insert_status_b(goods.id,"goods","to_dangerous_type_pool",self.env)
                        self.env.process(self._type_pool_exit_process_receive("dangerous_type_pool",goods))
                    elif goods.type == "refrigerated":
                        #self.sim_obj_manager.type_pool_dict["refrigerated_type_pool"].goods_list.append(goods)
                        insert_status_b(goods.id,"goods","to_refrigerated_type_pool",self.env)
                        self.env.process(self._type_pool_exit_process_receive("refrigerated_type_pool",goods))
                    
                    # 打印三个池的货物数量
                    # print(f"当前类型分类平台货物数量：{len(self.sim_obj_manager.type_pool_dict['type_pool'].goods_list)}")
                    # print(f"当前普通分类池货物数量：{len(self.sim_obj_manager.type_pool_dict['normal_type_pool'].goods_list)}")
                    # print(f"当前危险品分类池货物数量：{len(self.sim_obj_manager.type_pool_dict['dangerous_type_pool'].goods_list)}")
                    # print(f"当前冷藏分类池货物数量：{len(self.sim_obj_manager.type_pool_dict['refrigerated_type_pool'].goods_list)}")
                    # print(f"{self.env.now} 识别货物总数量：{len(self.sim_obj_manager.type_pool_dict['normal_type_pool'].goods_list)+len(self.sim_obj_manager.type_pool_dict['dangerous_type_pool'].goods_list)+len(self.sim_obj_manager.type_pool_dict['refrigerated_type_pool'].goods_list)}")
    """ 
    出口分类平台接收货物
    """
    def _type_pool_exit_process_receive(self,type:str,goods:Goods):
        """ 子分类平台接收货物 """
        yield self.env.timeout(10)
        # 检测是否有资源可用
        req=self.type_pool_sub_capacity_resources[type].request()
        yield req
        insert_status_b(goods.id,"goods",type,self.env)
        # 将请求对象保存到字典中，后续释放时使用
        self.type_pool_sub_requests[goods.id] = req
        # 将货物放入对应的分类池
        self.sim_obj_manager.type_pool_dict[type].goods_list.append(goods)
        # 打印三个池的货物数量
        # print(f"当前{type}分类池货物数量：{len(self.sim_obj_manager.type_pool_dict[type].goods_list)}")

    """ 
    出口分类平台处理逻辑：根据货物自身携带的出口id，将其放入绑定本类型的临时停放点
    """
    def _type_pool_exit_process(self, type: str):
        """
        这个方法中主要包含了三个出口分类平台实现出口分类的逻辑
        """
        while True:
            # 出口检查，每1s轮询一次
            yield self.env.timeout(3)
            # 检查有没有货物在分类池中
            if len(self.sim_obj_manager.type_pool_dict[type].goods_list) == 0:
                continue
            # 获取第一个货物
            goods=self.sim_obj_manager.type_pool_dict[type].goods_list[0]
            # 删除货物
            self.sim_obj_manager.type_pool_dict[type].goods_list.pop(0)

            goods.status_list.append(f"sub_type_check_finish_{goods.type}")
            # 释放出口分类平台的池资源
            if goods.id in self.type_pool_sub_requests:
                req = self.type_pool_sub_requests[goods.id]
                self.type_pool_sub_capacity_resources[type].release(req)
                del self.type_pool_sub_requests[goods.id]
            # 增加一步标识人工和机器的识别业务逻辑
            yield self.env.process(self.machine_man(goods))
            # sub_pool_process_list=["normal_type_pool","dangerous_type_pool","refrigerated_type_pool"]
            # co=0
            # for sub_pool in sub_pool_process_list:
            #     co+=len(self.sim_obj_manager.type_pool_dict[sub_pool].goods_list)
            # print(f"子分类平台的货物数量：{co}")
            # 将其放到各个出口分类平台的对应临时停放点
            check_point=""
            match type:
                case "normal_type_pool":
                    # 没有容量限制，直接放入
                    #self.sim_obj_manager.agv_pickup_point_dict[f"normal_1_{goods.exit_No}"].goods_list.append(goods)
                    # 检测容量，如果超出，则需要等待资源
                    # self.agv_pickup_point_resources[f"normal_1_{exit.id}"] 的资源是否已经没有了，如果没有了则检查 self.agv_pickup_point_resources[f"normal_2_{exit.id}"]，如果都没有则等待
                    k=f"normal_1_{goods.exit_No}"
                    if self.agv_pickup_point_resources[f"normal_1_{goods.exit_No}"].count == 0:
                        if self.agv_pickup_point_resources[f"normal_2_{goods.exit_No}"].count == 0:
                            req = self.agv_pickup_point_resources[f"normal_1_{goods.exit_No}"].request()
                        else:
                            req = self.agv_pickup_point_resources[f"normal_2_{goods.exit_No}"].request()
                            k=f"normal_2_{goods.exit_No}"
                    else:
                        req = self.agv_pickup_point_resources[f"normal_1_{goods.exit_No}"].request()
                    yield req
                    check_point=k
                    # 这里每一个id都是独立的 所以可以直接将请求资源存储到同一个容器中
                    self.agv_pickup_point_requests[goods.id] = req
                    self.sim_obj_manager.agv_pickup_point_dict[k].goods_list.append(goods)
                case "dangerous_type_pool":
                    # 没有容量限制，直接放入
                    # self.sim_obj_manager.agv_pickup_point_dict[f"dangerous_{goods.exit_No}"].goods_list.append(goods)
                    # 检测容量，如果超出，则需要等待资源
                    req = self.agv_pickup_point_resources[f"dangerous_{goods.exit_No}"].request()
                    yield req
                    check_point=f"dangerous_{goods.exit_No}"
                    self.agv_pickup_point_requests[goods.id] = req
                    self.sim_obj_manager.agv_pickup_point_dict[f"dangerous_{goods.exit_No}"].goods_list.append(goods)
                case "refrigerated_type_pool":
                    # 没有容量限制，直接放入
                    #self.sim_obj_manager.agv_pickup_point_dict[f"refrigerated_{goods.exit_No}"].goods_list.append(goods)
                    # 检测容量，如果超出，则需要等待资源
                    req = self.agv_pickup_point_resources[f"refrigerated_{goods.exit_No}"].request()
                    yield req
                    check_point=f"refrigerated_{goods.exit_No}"
                    self.agv_pickup_point_requests[goods.id] = req
                    self.sim_obj_manager.agv_pickup_point_dict[f"refrigerated_{goods.exit_No}"].goods_list.append(goods)
            # 记录存入 出口分类 临时停放点
            insert_status_b(goods.id,"goods",check_point,self.env)
            # 遍历获取所有出口对应的分类池的总货物数量
            # total_goods_num=0
            # exitcount=0
            # for exit in self.sim_obj_manager.exit_dict.values():
            #     exitcount=exitcount+1
            #     total_goods_num+=len(self.sim_obj_manager.agv_pickup_point_dict[f"normal_1_{exit.id}"].goods_list) + len(self.sim_obj_manager.agv_pickup_point_dict[f"normal_2_{exit.id}"].goods_list)+len(self.sim_obj_manager.agv_pickup_point_dict[f"dangerous_{exit.id}"].goods_list)+len(self.sim_obj_manager.agv_pickup_point_dict[f"refrigerated_{exit.id}"].goods_list)
            #     print(f"{self.env.now} 临时停放点货物数量 normal_1_{exit.id}：{len(self.sim_obj_manager.agv_pickup_point_dict[f'normal_1_{exit.id}'].goods_list)}")
            #     print(f"{self.env.now} 临时停放点货物数量 normal_2_{exit.id}：{len(self.sim_obj_manager.agv_pickup_point_dict[f'normal_2_{exit.id}'].goods_list)}")
            #     print(f"{self.env.now} 临时停放点货物数量 dangerous_{exit.id}：{len(self.sim_obj_manager.agv_pickup_point_dict[f'dangerous_{exit.id}'].goods_list)}")
            #     print(f"{self.env.now} 临时停放点货物数量 refrigerated_{exit.id}：{len(self.sim_obj_manager.agv_pickup_point_dict[f'refrigerated_{exit.id}'].goods_list)}")
            #     print()
            # print(f"{self.env.now} 临时停放点货物总数量：{total_goods_num}")
            # print(f"{self.env.now} 出口数量：{exitcount}")
            # print(f"{self.env.now} 临时停放点数量：{len(self.sim_obj_manager.agv_pickup_point_dict)}，每个停放点的容量 100")
            # print("--"*20)

    """ 
    增加一段 机器 人工 筛选的逻辑
    这里的逻辑主要是根据一定的概率 模拟机器的识别不出来的一个随机性
    """
    def machine_man(self,goods:Goods):
        randomValue= random.random()
        insert_status_b(goods.id,"goods","MACHINE_MAN",self.env)
        if randomValue<=MACHINE_RECOGNITION_RATIO:
            yield self.env.timeout(5)
            insert_status_b(goods.id,"goods","MACHINE",self.env)
            # 模拟机器识别所花费的时间
        else:
            yield self.env.timeout(20)
            insert_status_b(goods.id,"goods","MAN",self.env)
            # 模拟人工识别所花费的时间
        
        
        

    """ 
    空闲agv的check逻辑
    agv需要有一个检测紧急程度的算法，比如 普通平台 对应出口如果一个满了，另一个没有满，而危险的或者冷藏的已经满了，则需要有限处理非普通的
    同时，还需要有一个总控制，当所有的货物与总货物量已经相等了，也就是已经将所有货物都放在临时停放点了，则需要将每个临时停放点的货物都依次运出来不要遗留
    """
    def _run_agv_check(self,agv:AGV):
        while True:
            yield self.env.timeout(3)
            # 遍历所有出口
            for exit in self.sim_obj_manager.exit_dict.values():
                # 查看临时停放点是否满了 且是否被占用了
                n1=self.agv_pickup_point_resources[f"normal_1_{exit.id}"].count==AGV_PICKUP_POINT_CAPACITY and not self.sim_obj_manager.agv_pickup_point_dict[f"normal_1_{exit.id}"].is_occupied
                n2=self.agv_pickup_point_resources[f"normal_2_{exit.id}"].count==AGV_PICKUP_POINT_CAPACITY and not self.sim_obj_manager.agv_pickup_point_dict[f"normal_2_{exit.id}"].is_occupied
                d=self.agv_pickup_point_resources[f"dangerous_{exit.id}"].count==AGV_PICKUP_POINT_CAPACITY and not self.sim_obj_manager.agv_pickup_point_dict[f"dangerous_{exit.id}"].is_occupied
                r=self.agv_pickup_point_resources[f"refrigerated_{exit.id}"].count==AGV_PICKUP_POINT_CAPACITY and not self.sim_obj_manager.agv_pickup_point_dict[f"refrigerated_{exit.id}"].is_occupied
                if n1 or n2 or d or r:
                    # 有满的 临时停放点 开始判断优先级
                    if n1 and n2:
                        # 先标识占用，这样其他的车辆就不会占用他了
                        self.sim_obj_manager.agv_pickup_point_dict[f"normal_1_{exit.id}"].is_occupied=True
                        print(f"{self.env.now} 进入 临时停放点 normal_1_{exit.id} ")
                        insert_status_b(agv.id,"agv",f"to_normal_1_{exit.id}",self.env)
                        #再调用运输流程，这里直接等待整个流程结束再进入下一轮的逻辑
                        yield self.env.process(self._run_agv_transport(f"normal_1_{exit.id}",exit.id,agv))
                    else:
                        if r:
                            self.sim_obj_manager.agv_pickup_point_dict[f"refrigerated_{exit.id}"].is_occupied=True
                            print(f"{self.env.now} 进入 临时停放点 refrigerated_{exit.id}")
                            insert_status_b(agv.id,"agv",f"to_refrigerated_{exit.id}",self.env)
                            yield self.env.process(self._run_agv_transport(f"refrigerated_{exit.id}",exit.id,agv))
                            self.sim_obj_manager.agv_pickup_point_dict[f"refrigerated_{exit.id}"].is_occupied=False
                        elif d:
                            self.sim_obj_manager.agv_pickup_point_dict[f"dangerous_{exit.id}"].is_occupied=True
                            print(f"{self.env.now} 进入 临时停放点 dangerous_{exit.id}")
                            insert_status_b(agv.id,"agv",f"to_dangerous_{exit.id}",self.env)
                            yield self.env.process(self._run_agv_transport(f"dangerous_{exit.id}",exit.id,agv))
                            self.sim_obj_manager.agv_pickup_point_dict[f"dangerous_{exit.id}"].is_occupied=False
                        elif n2:
                            self.sim_obj_manager.agv_pickup_point_dict[f"normal_2_{exit.id}"].is_occupied=True
                            print(f"{self.env.now} 进入 临时停放点 normal_2_{exit.id}")
                            insert_status_b(agv.id,"agv",f"to_normal_2_{exit.id}",self.env)
                            yield self.env.process(self._run_agv_transport(f"normal_2_{exit.id}",exit.id,agv))
                            self.sim_obj_manager.agv_pickup_point_dict[f"normal_2_{exit.id}"].is_occupied=False
                        else:
                            self.sim_obj_manager.agv_pickup_point_dict[f"normal_1_{exit.id}"].is_occupied=True
                            print(f"{self.env.now} 进入 临时停放点 normal_1_{exit.id}")
                            insert_status_b(agv.id,"agv",f"to_normal_1_{exit.id}",self.env)
                            yield self.env.process(self._run_agv_transport(f"normal_1_{exit.id}",exit.id,agv))
                            self.sim_obj_manager.agv_pickup_point_dict[f"normal_1_{exit.id}"].is_occupied=False
            # 遍历所有的临时存放点，获取存放在上面的货品的数量
            temp_goods_num=0
            for exit in self.sim_obj_manager.exit_dict.values():
                if not self.sim_obj_manager.agv_pickup_point_dict[f"normal_1_{exit.id}"].is_occupied:
                    temp_goods_num+=len(self.sim_obj_manager.agv_pickup_point_dict[f"normal_1_{exit.id}"].goods_list)
                if not self.sim_obj_manager.agv_pickup_point_dict[f"normal_2_{exit.id}"].is_occupied:
                    temp_goods_num+=len(self.sim_obj_manager.agv_pickup_point_dict[f"normal_2_{exit.id}"].goods_list)
                if not self.sim_obj_manager.agv_pickup_point_dict[f"dangerous_{exit.id}"].is_occupied:
                    temp_goods_num+=len(self.sim_obj_manager.agv_pickup_point_dict[f"dangerous_{exit.id}"].goods_list)
                if not self.sim_obj_manager.agv_pickup_point_dict[f"refrigerated_{exit.id}"].is_occupied:
                    temp_goods_num+=len(self.sim_obj_manager.agv_pickup_point_dict[f"refrigerated_{exit.id}"].goods_list)
            if temp_goods_num>0 and (temp_goods_num + self.exit_goods_count)==GOODS_NUM: 
                for exit in self.sim_obj_manager.exit_dict.values():
                    if not self.sim_obj_manager.agv_pickup_point_dict[f"normal_1_{exit.id}"].is_occupied and len(self.sim_obj_manager.agv_pickup_point_dict[f"normal_1_{exit.id}"].goods_list)>0:
                        self.sim_obj_manager.agv_pickup_point_dict[f"normal_1_{exit.id}"].is_occupied=True
                        insert_status_b(agv.id,"agv",f"to_normal_1_{exit.id}",self.env)
                        yield self.env.process(self._run_agv_transport(f"normal_1_{exit.id}",exit.id,agv))
                        self.sim_obj_manager.agv_pickup_point_dict[f"normal_1_{exit.id}"].is_occupied=False
                    elif not self.sim_obj_manager.agv_pickup_point_dict[f"normal_2_{exit.id}"].is_occupied and len(self.sim_obj_manager.agv_pickup_point_dict[f"normal_2_{exit.id}"].goods_list)>0:
                        self.sim_obj_manager.agv_pickup_point_dict[f"normal_2_{exit.id}"].is_occupied=True
                        insert_status_b(agv.id,"agv",f"to_normal_1_{exit.id}",self.env)
                        yield self.env.process(self._run_agv_transport(f"normal_2_{exit.id}",exit.id,agv))
                        self.sim_obj_manager.agv_pickup_point_dict[f"normal_2_{exit.id}"].is_occupied=False
                    elif not self.sim_obj_manager.agv_pickup_point_dict[f"dangerous_{exit.id}"].is_occupied and len(self.sim_obj_manager.agv_pickup_point_dict[f"dangerous_{exit.id}"].goods_list)>0:
                        self.sim_obj_manager.agv_pickup_point_dict[f"dangerous_{exit.id}"].is_occupied=True
                        insert_status_b(agv.id,"agv",f"to_dangerous_{exit.id}",self.env)
                        yield self.env.process(self._run_agv_transport(f"dangerous_{exit.id}",exit.id,agv))
                        self.sim_obj_manager.agv_pickup_point_dict[f"dangerous_{exit.id}"].is_occupied=False
                    elif not self.sim_obj_manager.agv_pickup_point_dict[f"refrigerated_{exit.id}"].is_occupied and len(self.sim_obj_manager.agv_pickup_point_dict[f"refrigerated_{exit.id}"].goods_list)>0:
                        self.sim_obj_manager.agv_pickup_point_dict[f"refrigerated_{exit.id}"].is_occupied=True
                        insert_status_b(agv.id,"agv",f"to_refrigerated_{exit.id}",self.env)
                        yield self.env.process(self._run_agv_transport(f"refrigerated_{exit.id}",exit.id,agv))
                        self.sim_obj_manager.agv_pickup_point_dict[f"refrigerated_{exit.id}"].is_occupied=False

 


        
    
    """ 
    agv运输逻辑，到达对应出口之后，直接卸货
    并且释放agv的占用
    同时将货物放给出口
    """
    def _run_agv_transport(self,pick_up:str,exit_id:str, agv:AGV):
        # 模拟agv走到 临时停放点
        yield self.env.timeout(50)
        insert_status_b(agv.id,"agv",pick_up,self.env)
        # 模拟插起货物
        #agv.goods_list.append(self.sim_obj_manager.agv_pickup_point_dict[pick_up].goods_list)
        # 清空原有列表，才可继续放,同时需要释放原有的请求的资源
        for goods in self.sim_obj_manager.agv_pickup_point_dict[pick_up].goods_list:
            agv.goods_list.append(goods)
            # 释放货物的临时停放点的req
            self.agv_pickup_point_resources[pick_up].release(self.agv_pickup_point_requests[goods.id])
            self.exit_goods_count+=1
            insert_status_b(goods.id,"goods","agv_load",self.env)
            yield self.env.timeout(5)
        self.sim_obj_manager.agv_pickup_point_dict[pick_up].goods_list.clear()
        self.sim_obj_manager.agv_pickup_point_dict[pick_up].is_occupied=False

        # 模拟agv走到 出口
        yield self.env.timeout(50)
        # 找到出口，直接卸货
        exit=self.sim_obj_manager.exit_dict[exit_id]
        print(f"{self.env.now} 卸货到出口{exit.id}，货物总量 ")
        insert_status_b(agv.id,"agv",f"{exit_id}",self.env)
        for goods in agv.goods_list:
            # 增加申请卸货口的卸货指标，没有指标的则等待
            req=self.exit_buffer_resources[exit_id].request()
            yield req
            insert_status_b(goods.id,"goods","agv_unload",self.env)
            self.exit_buffer_requests[goods.id]=req
            exit.goods_list.append(goods)
            yield self.env.timeout(5)
        agv.goods_list.clear()
        #遍历所有出货口，计算货物总量
        total_goods_num=sum([len(exit.goods_list) for exit in self.sim_obj_manager.exit_dict.values()])
        print(f"{self.env.now} 出货口货物总量为{total_goods_num}")
        yield self.env.timeout(20)




    """ 
    停车站检测卡车是否能进入，类似对场外排队进站的车辆叫号
    这里模拟的是装货站的卡车的进站流程
    """
    def _run_truck_out(self):
        """运行卡车进入停靠站流程
        需要获取停靠站，同时检查是否还有货车未开入停车站，并获取当前的停靠站所有的车位有没有都被占用 都满足了，则放一辆车进来
        """
        while True:
            yield self.env.timeout(10)
            # 检查是否还有货车未开入停车站
            if len(self.sim_obj_manager.truck_dict) > 0:
                # 筛选truck type为 in ,并且status为spawn的卡车
                truck_list=[]
                for truck in self.sim_obj_manager.truck_dict.values():
                    if truck.type == "out" and truck.status == "spawn":
                        truck_list.append(truck)
                # 如果truck_list不为空，则获取一辆车
                if len(truck_list) > 0:
                    # 获取一辆车
                    truck=truck_list[0]
                    # print(f"放行卡车进入停车位{truck.id}")
                    # 申请停车位资源
                    parking_request = self.exit_parking_resource.request()
                    yield parking_request  # 等待获得资源
                    insert_status_b(truck.id,"out_truck","to_waiting",self.env)
                    # 将请求对象保存到字典中，后续释放时使用
                    self.truck_parking_requests[truck.id] = parking_request
                    # 修改车辆状态，设置成waiting，再模拟车辆从外部开到车位上
                    truck.status="waiting"
                    yield self.env.process(self._autorun_truck_out(truck.id))
                    insert_status_b(truck.id,"out_truck","waiting",self.env)
                    #yield self.env.timeout(1)
    
    """ 
    卡车进入停车场的过程，模拟从入口开到停车位
    """
    def _autorun_truck_out(self,truck_id:str):
        """自动运行卡车进入停靠站流程"""
        truck=self.sim_obj_manager.truck_dict[truck_id]
        # print(f"车辆{truck_id}从外部开到车位")
        yield self.env.timeout(50) # 模拟从外部开到车位
        # print(f"车辆{truck_id}从外部开到车位完成")

    """ 
    每个入口都绑定一个检测函数，先去检测是否有正在等待卸货的卡车，如果有，就申请卸货，绑定卡车后卡车开入这个入口，开始卸货
    直到卸货完成后，进入下一轮的检测
    """
    def _run_truck_Exit(self,exit_id:str):
        """ 卡车从车位走到卸货口，到达后开始卸货"""
        while True:
            yield self.env.timeout(5)
            # 检查有没有truck status 是 waiting 并且 type 是 in 的卡车
            truck_list=[]
            for truck in self.sim_obj_manager.truck_dict.values():
                if truck.status == "waiting" and truck.type == "out":
                    truck_list.append(truck)

            if len(truck_list) > 0:
                # 获取一辆车
                truck=truck_list[0]
                # 修改车辆状态，设置成unloading，再模拟车辆从车位到入口
                truck.status="loading"
                # 释放停车位资源 - 使用保存的请求对象
                if truck.id in self.truck_parking_requests:
                    parking_request = self.truck_parking_requests[truck.id]
                    self.exit_parking_resource.release(parking_request)
                    # 从字典中移除已释放的请求
                    del self.truck_parking_requests[truck.id]
                insert_status_b(truck.id,"out_truck","to_loading",self.env)
                # 等待装货进程完全完成，确保锁的正确释放
                yield self.env.process(self._autorun_truck_Exit(truck.id, exit_id))
                insert_status_b(truck.id,"out_truck","loading_finish",self.env)
    """ 
    装货口的具体装货流程
    首先每次都装一个，装之前检查是否是最后一件货物了，是的话结束装货
    当货车装满之后也直接停止装货
    """     
    def _autorun_truck_Exit(self,truck_id:str, exit_id:str):
        """自动运行卡车进入卸货口流程"""
        truck=self.sim_obj_manager.truck_dict[truck_id]
        exit=self.sim_obj_manager.exit_dict[exit_id]
        yield self.env.timeout(50) # 模拟从车位开到卸货口
        insert_status_b(truck.id,"out_truck","loading",self.env)
        # 这里添加装货逻辑
        while True:
            yield self.env.timeout(3)
            # 检查货物是否卸完
            if len(truck.goods_list) == truck.capacity:
                # 修改车辆状态，设置成finish
                truck.status="finish"
                break
            # 检测当前是否已经完全装完货物了，是的话直接结束
            if self.truck_load_count==GOODS_NUM:
                truck.status="finish"
                break
            # 若无货 则等待
            if len(exit.goods_list)==0:
                continue
            # 获取第一个货物，将其放入类型筛选平台
            goods=exit.goods_list[0]
            # 删除货物
            exit.goods_list.pop(0)
            # 修改货物状态，设置成 type check
            goods.status_list.append("truck_load")
            insert_status_b(goods.id,"goods","out_truck",self.env)
            # 释放原来的锁定的请求
            self.exit_buffer_resources[exit_id].release(self.exit_buffer_requests[goods.id])
            truck.goods_list.append(goods)
            self.truck_load_count+=1
            yield self.env.timeout(20) 
            # print(f"Time: {self.env.now} 当前装货总量为 {self.truck_load_count}")
            

    def run(self):
        """运行仿真流程"""
        # 绑定卡车进入停靠站流程
        self.env.process(self._run_truck_in())
        print("当前入口数量：",len(self.sim_obj_manager.enter_dict))
        # 绑定卡车进入入口流程
        for enter in self.sim_obj_manager.enter_dict.values():
            print(f"当前入口{enter.id}")
            self.env.process(self._run_truck_Enter(enter.id))

        # 添加分类平台的处理逻辑，将货物分类到对应的分类池中
        self.env.process(self._type_pool_process())
 
        # 添加出口分类平台的处理逻辑，将货物分类到对应的出口分类平台中
        sub_pool_process_list=["normal_type_pool","dangerous_type_pool","refrigerated_type_pool"]
        for sub_pool_process in sub_pool_process_list:
            self.env.process(self._type_pool_exit_process(sub_pool_process))

        # 给每一个agv添加check逻辑
        for agv in self.sim_obj_manager.agv_dict.values():
            self.env.process(self._run_agv_check(agv))

        # 绑定卡车进入停靠站流程
        self.env.process(self._run_truck_out())
        print("当前入口数量：",len(self.sim_obj_manager.enter_dict))
        # 绑定卡车进入入口流程
        for exit in self.sim_obj_manager.exit_dict.values():
            print(f"当前卸货口{exit.id}")
            self.env.process(self._run_truck_Exit(exit.id))
        
            
        
        
        
